#include "../Mylog.h"
#include <vector>
#include <thread>
#include <chrono>

void bench(const std::string& logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    //1.获取日志器
    mylog::Logger::ptr logger = mylog::GetLogger(logger_name);
    if(logger.get() == nullptr)
    {
        return;
    }
    std::cout << "测试日志: " << msg_count << "条, 总大小: " << (msg_len * msg_count / 1024) << "KB\n";
    //2.组织指定长度的日志消息
    std::string msg(msg_len - 1, 'A');//少一个字节添加换行
    //3.创建指定数量的线程
    size_t msg_prt_count = msg_count / thr_count;//每一个线程输出的日志数量
    std::vector<std::thread> threads;
    std::vector<double> cost_arry(thr_count);
    for(int i = 0; i < thr_count; i++)
    {
        threads.emplace_back([&, i](){
            //4.线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //5.开始循环写日志
            for(int j = 0; j < msg_prt_count; j++)
            {
                logger->fatal("%s", msg.c_str());
            }
            //6.线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            cost_arry[i] = cost.count();
            std::cout << "线程" << i << ":\t输出数量:" << msg_prt_count << ",耗时:" << cost.count() << "s" << std::endl;
        });
    }
    for(int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }
    //7.计算总耗时,耗时最长的线程就是总耗时
    double max_cost = cost_arry[0];
    for(int i = 0; i < thr_count; i++)
    {
        max_cost = max_cost > cost_arry[i] ? max_cost : cost_arry[i];
    }
    //8.进行输出打印
    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);
    std::cout << "总耗时: " << max_cost << "s\n";
    std::cout << "每秒输出日志数量: " << msg_per_sec << "条\n";
    std::cout << "每秒输出日志大小" << size_per_sec << "KB\n";
}
void sync_bench()//受磁盘影响
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->BuildLoggerName("sync_logger");
    builder->BuildFormatter("%m%n");
    builder->BuildSink<mylog::FileSink>("./logfile/sync.log");
    builder->BuildLoggerType(mylog::LoggerType::LOGGER_SYNC);
    builder->Build();
    bench("sync_logger", 1, 1000000, 100);
}
void async_bench()//受内存和CPU影响
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->BuildLoggerName("async_logger");
    builder->BuildFormatter("%m%n");
    builder->BuildSink<mylog::FileSink>("./logfile/async.log");
    builder->BuildLoggerType(mylog::LoggerType::LOGGER_ASYNC);
    builder->BuildENableUnsafe();//开启非安全模式将实际落地时间排除在外//减少磁盘交换时间
    builder->Build();
    bench("async_logger", 1, 1000000, 100);
}
int main()
{
    async_bench();
    return 0;
}